﻿using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Text;

namespace Kotonoha.Server.Objects.Model.Event {
    public class EventList {
        private static readonly Dictionary<EventTypes, Type> deserializeMap = new Dictionary<EventTypes, Type>();
        private static readonly Dictionary<Type, EventTypes> serializeMap = new Dictionary<Type, EventTypes>();
        private static readonly Type[] NoArguments = new Type[]{};
        private static readonly object[] NoParams = new object[]{};

        private static void Add(Type type, EventTypes ev) {
            deserializeMap.Add(ev, type);
            serializeMap.Add(type, ev);
        }

        static EventList() {
            Add(typeof(MarkEvent), EventTypes.Mark);
        }

        private readonly string logname;

        public EventList(string filename) {
            logname = filename;
        }

        public void save(Event e) {
            FileStream open = File.Open(logname, FileMode.Append, FileAccess.Write, FileShare.None);
            StreamWriter wr = new StreamWriter(open, Encoding.UTF8);
            wr.Write((uint)serializeMap[e.GetType()]);
            wr.Write(";");
            e.Serialize(wr);
            wr.Flush();
            wr.Close();
        }

        public IEnumerable<Event> load() {
            FileStream file = File.Open(logname, FileMode.Open, FileAccess.Read, FileShare.Read);
            StreamReader reader = new StreamReader(file);
            while (!reader.EndOfStream) {
                string line = reader.ReadLine();
                int idx = line.IndexOf(";");
                uint num = uint.Parse(line.Substring(0, idx));
                Event e = create((EventTypes)num);
                StringReader sr = new StringReader(line.Substring(idx + 1));
                e.Deserialize(sr);
                yield return e;
            }
            reader.Close();
        }

        private static Event create(EventTypes type) {
            Type t = deserializeMap[type];
            Event e = (Event) t.GetConstructor(NoArguments).Invoke(NoParams);
            return e;
        }
    }
}
